<?php

namespace App\Service;

use Exception;
use Illuminate\Http\Request;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Validation\ValidationException;
use Illuminate\Http\Exceptions\ThrottleRequestsException;
use \Overtrue\EasySms\Exceptions\NoGatewayAvailableException;
use App\Service\Traits\ApiResponse;

class ExceptionReport
{
    use ApiResponse;

    /**
     * @var Exception
     */
    public $exception;
    /**
     * @var Request
     */
    public $request;

    /**
     * @var
     */
    protected $report;

    /**
     * ExceptionReport constructor.
     * @param Request $request
     * @param Exception $exception
     */
    function __construct(Request $request, Exception $exception)
    {
        $this->request = $request;
        $this->exception = $exception;
    }

    /**
     * @var array
     */
    public $doReport = [
        AuthenticationException::class  => ['未授权', 401],
        ModelNotFoundException::class   => ['找不到该数据', 404],
        ValidationException::class      => ['validationHandler', 400],
        NoGatewayAvailableException::class => ['操作过于频繁,请稍后再试',400],
        ThrottleRequestsException::class=> ['throttleHandler', 400],

    ];

    /**
     * @return string
     */
    protected function throttleHandler() {
        /** @var ThrottleRequestsException $exception */

        $exception = $this->exception;
        return "操作过于频繁，请稍后再试";
    }

    /**
     * @return string
     */
    protected function validationHandler() {
        /** @var ValidationException $exception */

        $exception = $this->exception;
        return $exception->validator->errors()->first();
    }

    /**
     * @return bool
     */
    public function shouldReturn()
    {
        foreach (array_keys($this->doReport) as $report) {
            if ($this->exception instanceof $report) {
                $this->report = $report;
                return true;
            }
        }
        return false;
    }

    /**
     * @param Exception $e
     * @return static
     */
    public static function make(Exception $e)
    {
        return new static(\request(), $e);
    }

    /**
     * @return mixed
     */
    public function report()
    {
        list($message, $code) = $this->doReport[$this->report];
        if (method_exists($this, $message)) {
            $message = call_user_func([$this, $message]);
        }

        if ($this->request->wantsJson() || $this->request->ajax()) {
            return $this->failed($message, $code);
        }else {
            return $this->failed($message, $code);        
        }
    }
}
